using System;
using System.Runtime.Serialization;
using OhioState.AssetManaged;

namespace OhioState.Graphics.Proxy
{
    /// <summary>
    /// BoxBoundary class defines the boundary of a box
    /// </summary>
    [Serializable()]
    public class BoxBoundaryProxy :SharedAsset, IDrawable
    {
        #region Public Properties
        private bool _drawBackFaces = true;
        /// <summary>
        /// Get/Set Accessors for Backface drawing
        /// </summary>
        public bool DrawBackFaces
        {
            get { return _drawBackFaces; }
            set
            {
                _drawBackFaces = value;
                FireUpdateChangedEvent(this);
            }
        }
        private bool _drawFrontFaces = true;
        /// <summary>
        /// Get/Set Accessors for Front face drawing
        /// </summary>
        public bool DrawFrontFaces
        {
            get { return _drawFrontFaces; }
            set
            {
                _drawFrontFaces = value;
                FireUpdateChangedEvent(this);
            }
        }
        private SharedBox _box;

        /// <summary>
        /// Get/Set Accessor for the box for which boundary is defines
        /// </summary>
        public SharedBox Box
        {
            get { return _box; }
            set
            {
                IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                this.SetPropertyEventHandling(_box, value, changedEvent);
                _box = value;
                Box_ChangedEvent(_box);
            }

        }

        /// <summary>
        /// Implementation of IBoundingVolume BoundingVolume accessor
        /// </summary>
        public IBoundingVolume BoundingVolume
        {
            get { return _box.BBox; }
        }

       
        private MaterialProxy _material;
        /// <summary>
        /// Get/Set Accessor for the material of the boundary proxy
        /// </summary>
        public IMaterial Material
        {
            get { return _material; }
            set
            {
                //
                // For fields that contain shared objects, follow this sequence:
                //   1. rewire the notification for the shared object
                //        this property points to.
                //   2. set the property.
                //   3. perform any internal updates.
                //   4. Implicit in step 3 would be changing this 
                //         object and hence notifying it's subscribers.
                //
                MaterialProxy mat = value as MaterialProxy;
                if (mat != null)
                {
                    IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                    this.SetPropertyEventHandling(_material, mat, changedEvent);
                    _material = mat;
                    Box_ChangedEvent(mat);
                }
            }
        }
        #endregion Public Properties

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name">name of the object</param>
        /// <param name="box">input box</param>
        public BoxBoundaryProxy(String name, SharedBox box)
            : base(name)
        {
            _box = box;
            _material = MaterialProxy.White;
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box.AddChangedEventHandler(changedEvent);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="box">input box</param>
        public BoxBoundaryProxy(SharedBox box)
            : this("", box)
        {
        }
        /// <summary>
        /// Implementation of IDrawable Render method
        /// </summary>
        /// <param name="panel">Renderable panel</param>
        public virtual void Render(IRenderPanel panel)
        {
        }
        //public void Update(IRenderPanel panel)
        //{
        //}
        private void Box_ChangedEvent(IAssetManaged obj)
        {
            FireUpdateChangedEvent(this);
        }
        /// <summary>
        /// Overrides shared object ToString method
        /// </summary>
        /// <returns>A string representing parent shared object name</returns>
        public override String ToString()
        {
            return base.Name;
        }
        /// <summary>
        /// Implementation of SharedAsset ReaquireAssets method
        /// </summary>
        public override void ReaquireAssets()
        {
            //
            // Use the Properties to ensure the old event handlers are removed and new
            //    ones are added. Particularly if we are setting an item to itself.
            //
            IAssetManaged item = AssetManager.Instance.Find(_box.GetType(), _box.Name);
            if (item != _box)
            {
                this.Box = item as SharedBox;
            }
            item = AssetManager.Instance.Find(_material.GetType(), _material.Name);
            if (item != _material)
            {
                this.Material = item as IMaterial;
            }
        }
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box.AddChangedEventHandler(changedEvent);
            _material.AddChangedEventHandler(changedEvent);
        }
    }
}
